package im_server

import (
	"crypto/sha256"
	"encoding/hex"
	"errors"
	"fmt"
	"github.com/google/uuid"
	"io"
	"os"
	"pim/pkg/models"
	"pim/pkg/tools"
	"time"
)

func (c *ClientConn) CreateUploadTaskApi(req *models.CreateUploadTaskReq) (resp *models.CreateUploadTaskResp, err error) {

	// 创建文件
	userPath := fmt.Sprintf("%s/%d", c.svr.config.Workspace, c.UserID)
	// 校验并创建
	err = tools.CheckAndCreateDir(userPath)
	if err != nil {
		return
	}

	newFilePath := fmt.Sprintf("%s/%s", userPath, req.FileName)

	timeNow := time.Now()
	taskObj := &FileTaskInfo{
		Name:       req.FileName,
		Sha256:     req.Hash,
		FileSize:   req.FileSize,
		CreateTime: timeNow.UnixMilli(),
		Path:       userPath,
	}

	newFile, err := os.OpenFile(newFilePath, os.O_CREATE|os.O_RDWR, os.ModePerm)
	if err != nil {

		return
	}

	taskObj.file = newFile
	uuidInt := int64(uuid.New().ID())
	c.cacheUploadFileMap[uuidInt] = taskObj

	resp = new(models.CreateUploadTaskResp)
	resp.FileID = uuidInt

	return
}

func (c *ClientConn) StopUploadTaskApi(req *models.StopUploadTaskReq) (resp *models.StopUploadTaskResp, err error) {
	taskInfo, isok := c.cacheUploadFileMap[req.FileID]
	if !isok {
		err = errors.New("not found task")
		return
	}

	taskInfo.Delete()

	return
}
func (c *ClientConn) SendUploadPackageApi(req *models.SendUploadPackageReq) (resp *models.SendUploadPackageResp, err error) {
	resp = new(models.SendUploadPackageResp)
	crc8 := tools.GetCrc8(req.Body)
	resp.Crc = int(crc8)
	// 查找任务
	taskInfo, isok := c.cacheUploadFileMap[req.FileID]
	if !isok {
		err = errors.New("task not found")
		return
	}

	if taskInfo.file == nil {
		err = errors.New("file not create")
		return
	}

	if req.Offset == taskInfo.CurrentOffset {
		// 直接写入
		rLen, errWrite := taskInfo.file.Write(req.Body)
		if errWrite != nil {
			err = errWrite
			return
		}
		taskInfo.CurrentOffset += rLen
		return
	} else {
		// 移动到指定的位置
		_, err = taskInfo.file.Seek(int64(req.Offset), 0)
		if err != nil {
			return
		}

		rlen, errWrite := taskInfo.file.Write(req.Body)
		if errWrite != nil {
			err = errWrite
			return
		}

		taskInfo.CurrentOffset = taskInfo.CurrentOffset + rlen
		return

	}
	//taskInfo.file.Seek(int64(req.Offset), 0)

	return
}

func (c *ClientConn) ContinueUploadPackageApi(req *models.ContinueUploadPackageReq) (resp *models.ContinueUploadPackageResp, err error) {
	return
}
func (c *ClientConn) PauseUploadPackageReqApi(req *models.PauseUploadPackageReq) (resp *models.PauseUploadPackageResp, err error) {
	return
}
func (c *ClientConn) DoneUploadPackageApi(req *models.DoneUploadPackageReq) (resp *models.DoneUploadPackageResp, err error) {

	taskInfo, isok := c.cacheUploadFileMap[req.FileID]
	if !isok {
		err = errors.New("not found task")
		return
	}

	sha256Tool := sha256.New()

	taskInfo.file.Seek(0, 0)

	buffer, bufferErr := io.ReadAll(taskInfo.file)
	_ = bufferErr

	sha256Tool.Write(buffer)
	sha256Hex := sha256Tool.Sum(nil)

	resultSha256 := hex.EncodeToString(sha256Hex)

	if taskInfo.Sha256 != resultSha256 {
		// 传输失败
		// 结束任务 删除文加
		taskInfo.Delete()
		return
	}

	// 任务结束
	//保存 文件
	err = taskInfo.Save()
	// 返回路径

	//TODO 保存数据库文件信息

	uuidSha := fmt.Sprintf("%d:%s:%s", c.UserID, taskInfo.Name, resultSha256)

	uuidFile := tools.JenkinsHash([]byte(uuidSha))

	item := &models.FileUUID{
		FileName:  taskInfo.Name,
		UserID:    c.UserID,
		FileSize:  taskInfo.FileSize,
		Sha256:    sha256Hex,
		CreatedAt: taskInfo.CreateTime,
		UUID:      uuidFile,
	}

	db := c.svr.db
	err = db.Create(item).Error
	if err != nil {
		err = errors.New("保存数据库失败")
		return
	}

	resp = new(models.DoneUploadPackageResp)
	//resp.FileUUID =

	return
}

//void main()  {
//	restart:
//
//	exit := AppMain()
//	if exit == 9999 {
//		goto restart
//	}
//}
//
//void AppMain()  {
//	// do something
//}
